-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Customizer: Allow arbitrary custom CSS #10667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Customizer: Allow arbitrary custom CSS #10667
Conversation
This reverts commit 6c6a72b.
…er-allow-arbitrary-custom-css
Arbitrary CSS is allowed and escaped when printed.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
westonruter
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple trivial suggestions, but otherwise this looks great.
Co-authored-by: Weston Ruter <[email protected]>
Co-authored-by: Weston Ruter <[email protected]>
…er-allow-arbitrary-custom-css
…er-allow-arbitrary-custom-css
|
#10641 includes some protection to ensure bad style tag contents are not saved (including This change should be fine because of the work in #10656. Is it worth including that additional safety here? On one hand, this change should be perfectly safe now. On the other hand, there's not a very good reason to allow possible style tag closers inside of style tags. It will be safely escaped by the HTML API, but I wonder whether it's more helpful to prevent it from ever being stored. |
|
In other words, to restore the if ( preg_match( '#</?\w+#', $css ) ) {To be rather: if ( false !== stripos( $css, '</style' ) ) {Right? That seems fine to me. To be more conservative, and only make it even looser if we find this is actually needed. |
|
The check I've proposed is a bit more complicated. It also covers text that ends in partial style close tags The HTML API should still protect against broken style tag contents, so I'm not sure whether this protection is worth bringing here as well. code sample protected function validate_custom_css( $css ) {
$length = strlen( $css );
for (
$at = strcspn( $css, '<' );
$at < $length;
$at += strcspn( $css, '<', ++$at )
) {
$remaining_strlen = $length - $at;
$possible_style_close_tag = 0 === substr_compare( $css, '</style', $at, min( 7, $remaining_strlen ), true );
if ( $possible_style_close_tag ) {
if ( $remaining_strlen < 8 ) {
return new WP_Error(
'rest_custom_css_illegal_markup',
sprintf(
/* translators: %s is the CSS that was provided. */
__( 'The CSS must not end in "%s".' ),
esc_html( substr( $css, $at ) )
),
array( 'status' => 400 )
);
}
if ( 1 === strspn( $css, " \t\f\r\n/>", $at + 7, 1 ) ) {
return new WP_Error(
'rest_custom_css_illegal_markup',
sprintf(
/* translators: %s is the CSS that was provided. */
__( 'The CSS must not contain "%s".' ),
esc_html( substr( $css, $at, 8 ) )
),
array( 'status' => 400 )
);
}
}
}
return true;
} |
sirreal
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to rework this based on what landed in r61486.
No, I'm not. This is ready to go, I'll land it. |
|
Can we get test coverage added for the example CSS in the PR description? |
peterwilsoncc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit pick inline.
Some users may have the customize capability but not the unfiltered_html capability.
For those users I think it would be good to run urls through the kses protocol check, see this section of code in the safe css portion of kses.
wordpress-develop/src/wp-includes/kses.php
Lines 2885 to 2908 in 6d60f73
| if ( $found && $url_attr ) { | |
| // Simplified: matches the sequence `url(*)`. | |
| preg_match_all( '/url\([^)]+\)/', $parts[1], $url_matches ); | |
| foreach ( $url_matches[0] as $url_match ) { | |
| // Clean up the URL from each of the matches above. | |
| preg_match( '/^url\(\s*([\'\"]?)(.*)(\g1)\s*\)$/', $url_match, $url_pieces ); | |
| if ( empty( $url_pieces[2] ) ) { | |
| $found = false; | |
| break; | |
| } | |
| $url = trim( $url_pieces[2] ); | |
| if ( empty( $url ) || wp_kses_bad_protocol( $url, $allowed_protocols ) !== $url ) { | |
| $found = false; | |
| break; | |
| } else { | |
| // Remove the whole `url(*)` bit that was matched above from the CSS. | |
| $css_test_string = str_replace( $url_match, '', $css_test_string ); | |
| } | |
| } | |
| } |
Apart from that I think it's fine to bypass kses, the allow list it currently uses is currently dated and represents a time that browsers where less secure than they are now.
This may not be entirely relevant here because the Custom CSS requires the
And this is treated the same as wordpress-develop/src/wp-includes/capabilities.php Lines 594 to 595 in 1fdc11a
|
I believe this is covered by
I'm reluctant to add this if avoidable. If there are specific concerns I'm happy to work on addressing them. Do you know whether this filter was already being run on the content? One concern I have is that these functions are working with HTML entities, indicating they're not designed to operate on CSS or the RAWTEXT content of STYLE tags. This type of content-type processing mismatch is why this change is necessary. wordpress-develop/src/wp-includes/kses.php Lines 1995 to 2007 in bee3356
wordpress-develop/src/wp-includes/kses.php Lines 2030 to 2043 in bee3356
|
|
Thanks everyone! I believe all feedback is addressed. |
Under some circumstances KSES would run post content filters and change the resulting content like this:
@property --animate { - syntax: "<custom-ident>"; + syntax: ""; inherits: true; initial-value: false; }✅ Merged in [61418]. ~This depends on #10656 to ensure styles output is safely printed in the HTML (merged here).`
r61486 relaxed CSS content checks for Global styles with some additional restrictions that do not apply here.
Trac ticket: https://core.trac.wordpress.org/ticket/64418
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.